home *** CD-ROM | disk | FTP | other *** search
- //***********************************************************************
- //
- // Threads.cpp
- //
- //***********************************************************************
-
- #include <afxwin.h>
- #include <math.h>
- #include "Resource.h"
- #include "Threads.h"
-
- #define RADIUS 120
-
- CMyApp myApp;
-
- /////////////////////////////////////////////////////////////////////////
- // CMyApp member functions
-
- BOOL CMyApp::InitInstance ()
- {
- m_pMainWnd = new CMainWindow;
- m_pMainWnd->ShowWindow (m_nCmdShow);
- m_pMainWnd->UpdateWindow ();
- return TRUE;
- }
-
- /////////////////////////////////////////////////////////////////////////
- // CMainWindow message map and member functions
-
- BEGIN_MESSAGE_MAP (CMainWindow, CFrameWnd)
- ON_WM_CLOSE ()
- ON_COMMAND_RANGE (IDM_THREAD_1, IDM_THREAD_4, OnToggleThread)
- ON_COMMAND (IDM_FRIENDLY_THREADS, OnFriendlyThreads)
- ON_UPDATE_COMMAND_UI_RANGE (IDM_THREAD_1, IDM_THREAD_4,
- OnUpdateThreadUI)
- ON_UPDATE_COMMAND_UI (IDM_FRIENDLY_THREADS,
- OnUpdateFriendlyThreadsUI)
- ON_COMMAND (IDM_EXIT, OnExit)
- END_MESSAGE_MAP ()
-
- CMainWindow::CMainWindow ()
- {
- m_bFriendlyThreads = FALSE;
- for (int i=0; i<4; i++) {
- m_pThread[i] = NULL;
- m_bContinue[i] = FALSE;
- }
-
- CString strWndClass = AfxRegisterWndClass (
- 0,
- myApp.LoadStandardCursor (IDC_ARROW),
- (HBRUSH) (COLOR_3DFACE + 1),
- myApp.LoadStandardIcon (IDI_APPLICATION)
- );
-
- Create (strWndClass, "Threads", WS_OVERLAPPEDWINDOW, rectDefault,
- NULL, MAKEINTRESOURCE (IDR_MAINFRAME));
-
- LoadAccelTable (MAKEINTRESOURCE (IDR_MAINFRAME));
- }
-
- BOOL CMainWindow::PreCreateWindow (CREATESTRUCT& cs)
- {
- if (!CFrameWnd::PreCreateWindow (cs))
- return FALSE;
-
- cs.dwExStyle &= ~WS_EX_CLIENTEDGE;
- return TRUE;
- }
-
- void CMainWindow::OnClose ()
- {
- for (int i=0; i<4; i++) {
- if (m_pThread[i] != NULL)
- delete m_pThread[i];
- }
- CFrameWnd::OnClose ();
- }
-
- void CMainWindow::OnToggleThread (UINT nID)
- {
- static int nCoords[4][2] = {
- RADIUS, -RADIUS, // Thread 1
- RADIUS * 3, -RADIUS, // Thread 2
- RADIUS, -RADIUS * 3, // Thread 3
- RADIUS * 3, -RADIUS * 3 // Thread 4
- };
-
- UINT i = nID - IDM_THREAD_1;
-
- if (m_pThread[i] == NULL) { // Create a thread
- THREADPARMS* pThreadParms = new THREADPARMS;
- pThreadParms->point.x = nCoords[i][0];
- pThreadParms->point.y = nCoords[i][1];
- pThreadParms->pContFlag = &m_bContinue[i];
- pThreadParms->pFriendFlag = &m_bFriendlyThreads;
- pThreadParms->lParam = (LPARAM) this;
-
- m_bContinue[i] = TRUE;
- m_pThread[i] = AfxBeginThread (ThreadFunc, pThreadParms);
- }
- else { // Terminate a thread
- HANDLE hThread = m_pThread[i]->m_hThread;
- m_bContinue[i] = FALSE;
- ::WaitForSingleObject (hThread, INFINITE);
- m_pThread[i] = NULL;
- }
- }
-
- void CMainWindow::OnFriendlyThreads ()
- {
- m_bFriendlyThreads = m_bFriendlyThreads ? FALSE : TRUE;
- }
-
- void CMainWindow::OnUpdateFriendlyThreadsUI (CCmdUI* pCmdUI)
- {
- pCmdUI->SetCheck (m_bFriendlyThreads);
- }
-
- void CMainWindow::OnExit ()
- {
- SendMessage (WM_CLOSE, 0, 0);
- }
-
- void CMainWindow::OnUpdateThreadUI (CCmdUI* pCmdUI)
- {
- UINT i = pCmdUI->m_nID - IDM_THREAD_1;
-
- CString string;
- if (m_pThread[i] == NULL)
- string.Format ("Start Thread &%d\tF%d", i + 1, i + 1);
- else
- string.Format ("Terminate Thread &%d\tF%d", i + 1, i + 1);
-
- pCmdUI->SetText (string);
- }
-
- void CMainWindow::DrawHand (CDC* pDC, int nLength, int nScale,
- int nDegrees, COLORREF crColor)
- {
- CPoint point[4];
- double nRadians = (double) nDegrees * 0.017453292;
-
- point[0].x = (int) (nLength * sin (nRadians));
- point[0].y = (int) (nLength * cos (nRadians));
-
- point[2].x = -point[0].x / nScale;
- point[2].y = -point[0].y / nScale;
-
- point[1].x = -point[2].y;
- point[1].y = point[2].x;
-
- point[3].x = -point[1].x;
- point[3].y = -point[1].y;
-
- CPen pen (PS_SOLID, 0, crColor);
- CPen* pOldPen = pDC->SelectObject (&pen);
-
- pDC->MoveTo (point[0]);
- pDC->LineTo (point[1]);
- pDC->LineTo (point[2]);
- pDC->LineTo (point[3]);
- pDC->LineTo (point[0]);
-
- pDC->SelectObject (pOldPen);
- }
-
- UINT CMainWindow::ThreadFunc (LPVOID pParam)
- {
- static COLORREF crColors[8] = {
- RGB ( 0, 0, 0), // Black
- RGB ( 0, 0, 255), // Blue
- RGB ( 0, 255, 0), // Green
- RGB ( 0, 255, 255), // Cyan
- RGB (255, 0, 0), // Red
- RGB (255, 0, 255), // Magenta
- RGB (255, 255, 0), // Yellow
- RGB (255, 255, 255) // White
- };
-
- THREADPARMS* pThreadParms = (THREADPARMS*) pParam;
- CPoint point = pThreadParms->point;
- BOOL* pContFlag = pThreadParms->pContFlag;
- BOOL* pFriendFlag = pThreadParms->pFriendFlag;
- CMainWindow* pWnd = (CMainWindow*) pThreadParms->lParam;
- delete pThreadParms;
-
- int nMinute = 0;
- int nIndex = 0;
-
- while (*pContFlag) {
- CDC* pDC = pWnd->GetDC ();
- pDC->SetMapMode (MM_LOENGLISH);
-
- CPoint org = point;
- pDC->LPtoDP (&org);
- pDC->SetViewportOrg (org.x, org.y);
-
- pWnd->DrawHand (pDC, RADIUS, 8, nMinute * 6, crColors[nIndex]);
- pWnd->ReleaseDC (pDC);
-
- if (++nMinute == 60) {
- nMinute = 0;
- if (++nIndex == 8)
- nIndex = 0;
- }
-
- if (*pFriendFlag)
- ::Sleep (0);
- }
- return 0;
- }
-